#[test]
fn iterator_demonstration(){
    let v1 = vec![1, 2, 3];
    let mut viter = v1.iter();
    assert_eq!(viter.next(), Some(&1));
    assert_eq!(viter.next(), Some(&2));
    assert_eq!(viter.next(), Some(&3));
    assert_eq!(viter.next(), None);
}

#[test]
fn iter_sum(){
    let v1 = vec![1, 2, 3];
    let v1_iter = v1.iter();
    let total:i32 = v1_iter.sum();
    assert_eq!(total, 6);
    // println!("{:?}", v1_iter.next());
}

#[test]
fn iter_map(){
    let v1 = vec![1, 2, 3];
    let v2:Vec<_> = v1.iter().map(|x|(x+1).to_string()).collect();
    assert_eq!(v2, ["2", "3", "4"])
}

#[derive(PartialEq, Debug)]
struct Shoe{
    size: u32,
    style: String,
}

fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32)->Vec<Shoe>{
    shoes.into_iter().filter(|s| s.size==shoe_size).collect()
}

#[test]
fn filter_by_size(){
    let shoes = vec![
        Shoe{ size: 10, style: String::from("Sneaker") },
        Shoe{ size: 13, style: String::from("sandal") },
        Shoe{ size: 10, style: String::from("boot") },
    ];

    let my_size = shoes_in_my_size(shoes, 10);
    assert_eq!(my_size, vec![
        Shoe{ size: 10, style: String::from("Sneaker") },
        Shoe{ size: 10, style: String::from("boot") },
    ])
}

struct MyCounter{
    counter: u32,
}

impl MyCounter {
    fn new()->MyCounter{
        MyCounter{
            counter: 0
        }
    }
}

impl Iterator for MyCounter{
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.counter +=1 ;
        if self.counter<6{
            Some(self.counter)
        }else {
            None
        }
    }
}

#[test]
fn test_self_iterator(){
    let mut counter = MyCounter::new();
    assert_eq!(counter.next(), Some(1));
    assert_eq!(counter.next(), Some(2));
    assert_eq!(counter.next(), Some(3));
    assert_eq!(counter.next(), Some(4));
    assert_eq!(counter.next(), Some(5));
    assert_eq!(counter.next(), None);
}

#[test]
fn test_zip_skip(){
    let sm:u32 = MyCounter::new()
        .zip(MyCounter::new().skip(1))
        .map(|(a, b)|a*b)
        .filter(|e| e%3==0)
        .sum();
    assert_eq!(sm, 18);
}